#pragma once
#include "Vertex.hpp"
#include "QD3D/QD3DResourcePack.h"
#include <QD3D/QD3DUtils.h>
#include <glm/glm.hpp>
#include "../src/corelib/tools/qvector.h"

class Octree
{
public:
	CONST_STRUCT_BEGIN(OctreeStructInfo)
		UINT maxLevel;
		float boxSize;
		UINT elemNum;
	CONST_STRUCT_END

	struct Node
	{
		Node ()
		{
			memset (this, 0xFFFFFFFF, sizeof (Node));
			int verticesNum = 0;
		}
		UINT key;
		int verticesBaseIdx;
		int verticesNum;
		int parentIdx;
		int childIdxs[8];
		int neighborIdxs[27];
		int nodeVertexIdxs[8];
		int nodeEdgeIdxs[12];
		static const char *s_HLSL_STRUCT_STR;
	};

	struct NodeVertex
	{
		NodeVertex ()
		{
			loc = glm::vec3 (0, 0, 0);
			valid = 0;
			memset (nodeIdxs, -1, 8 * sizeof (int));
		}
		glm::vec3 loc;
		int valid;
		int nodeIdxs[8];
		static const char *s_HLSL_STRUCT_STR;
	};

	struct NodeVertexValue
	{
		float value;
		glm::vec3 normal;
		glm::vec3 color;
		static const char *s_HLSL_STRUCT_STR;
	};

	struct NodeEdge
	{
		NodeEdge ()
		{
			memset (this, -1, sizeof (NodeEdge));
			valid = 0;
		}
		int valid;
		int vertexIdx;
		int nodeVertexIdxs[2];
		int nodeIdxs[4];
		static const char *s_HLSL_STRUCT_STR;
	};

	QVector< Node > finalNodesBufInitData;
	QVector< NodeVertex > nodeVerticesBufInitData;
	QVector< NodeEdge > nodeEdgesBufInitData;

	OctreeStructInfo structInfo;

	ID3D11Buffer *p_octreeInfoDxConstBuf;
	QD3DResourcePack *p_verticesPack;
	QD3DResourcePack *p_nodesPack;
	QD3DResourcePack *p_nodeVerticesPack;
	QD3DResourcePack *p_nodeEdgesPack;
	QD3DResourcePack *p_nodeVerticeValuesPack;
	QD3DResourcePack *p_levelPack;

	Octree (UINT boxSize, UINT elemNum, UINT maxLevels, UINT origVertexNum);
	~Octree ();

	void clear ();
};




// #define NODE_HLSL_STRUCT \
// 	"struct Node" \
// 	"{" \
// 	"	uint key;" \
// 	"	int verticesBaseIdx;" \
// 	"	int verticesNum;" \
// 	"	int parentIdx;" \
// 	"	int childIdxs[8];" \
// 	"	int neighborIdxs[27];" \
// 	"	int nodeVertexIdxs[8];" \
// 	"	int nodeEdgeIdxs[12];" \
// 	"};"
// 
// #define NODE_VERTEX_HLSL_STRUCT \
// 	"struct NodeVertex" \
// 	"{" \
// 	"float3 loc;" \
// 	"int valid;" \
// 	"int nodeIdxs[8];" \
// 	"};"
// #define NODE_EDGE_STRUCT \
// 	"struct NodeEdge" \
// 	"{" \
// 	"int valid;" \
// 	"int vertexIdx;" \
// 	"int nodeVertexIdxs[2];" \
// 	"int nodeIdxs[4];" \
// 	"};"
